/** 
    Copyright 2010 Henrik Andersson
    
    This file is part of Loopist.

    Loopist is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Loopist is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Loopist.  If not, see <http://www.gnu.org/licenses/>.
*/


package se.dinamic.loopist;

import android.util.Log;

import java.util.Random;
import java.nio.ByteBuffer;
import java.nio.ShortBuffer;

/** Metronome track ar used as referenced for empty tracks.  */
public class MetronomeTrack extends Track {
	
	
	public final static short TICK_DATA[] = { 
		500,1000,4000,8000,16000,24000,30000,31000,32000,31000,30000,24000,16000,8000,6000,4000,
		3000,2500,2000,1500,1250,1000,750,500,450,400,350,300,275,250,225,200,175,150,125,100,0 
	};
	
	private static int _bars;
	private static int _beatsPerBar;
	private static ShortBuffer _tickPcm = null;
	private static ShortBuffer _tickPcmLow = null;
	
	private static void setClick(ByteBuffer clickPcm)  {
		// Setup low volume tick from base sample
		if( clickPcm != null ) {
			int size=clickPcm.capacity()/2;
			_tickPcm= ShortBuffer.allocate( size );
			_tickPcm.mark();
			_tickPcmLow = ShortBuffer.allocate( size );
			_tickPcmLow.mark();
			
			for( int f=0;f< size ; f++) {
				short sample = clickPcm.getShort();
				_tickPcm.put( sample );
				_tickPcmLow.put( (short)(sample*0.4f) );
			}
			_tickPcm.reset();
			_tickPcmLow.reset();
		}
	}
	
	public static MetronomeTrack generateTrack(int bpm,int bars,int bpb,ByteBuffer clickPcm) {
		
		
		int frames = (int) ( ( ( bars * bpb ) / ( bpm / 60.0f ) ) * 44100.0f );
		MetronomeTrack._bars=bars;
		MetronomeTrack._beatsPerBar=bpb;
		
		MetronomeTrack.setClick( clickPcm );
		MetronomeTrack track = new MetronomeTrack( frames );
		
		return track;
	}
	
	private MetronomeTrack(int frames) { 
		super(frames);
		Log.v("Loopist","MetronomeTrack() Creating metronome track "+(frames/44100.0f)+" seconds long ("+frames+" frames)."); 
		
		// Add metronome ticks to track
		int framestep = ( getFrameCount() / _bars ) / _beatsPerBar;
		Log.v("Loopist","MetronomeTrack() Each beat 4th beat in bar is "+(framestep/44100.0f)+" seconds long."); 
		
		// For each 4th beat add mentronome tick
		if( _tickPcm != null ) {
			int offset=0;
			ShortBuffer track=getBuffer();
			track.clear();
			for(int t=0;t<(_bars*_beatsPerBar);t++) {
				track.position(offset); // Advance to next beat posistion
				_tickPcm.mark();
				_tickPcmLow.mark();
				
				track.mark(); // First add a mark of current beat position
				if( t%4 == 0 )
					track.put( _tickPcm ); // Add tick standard sample data
				else
					track.put( _tickPcmLow ); // Add low amplituded sample data
				
				track.reset(); // Go back to start of current beat position
				_tickPcm.reset();
				_tickPcmLow.reset();
				offset+=framestep;
			}
		}
	}
}